﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Diagnostics;
using System.Threading;

namespace Bing4Free
{
	public partial class MainForm : Form
	{
		public static MainForm Instance;
		private List<WallpaperImageList> WallpaperImageListCollection;
		private Thread downloadThread;

		private bool isBeginDownload = false;
		public bool IsBeginDownload { get { return isBeginDownload; } set { isBeginDownload = value; } }

		private bool proxyEnabled = false;
		public bool ProxyEnabled { get { return UseProxyCheckBox.Checked; } }

		private string proxyServer = string.Empty;
		public string ProxyServer { get { return ProxyServerTextBox.Text.Trim(); } }

		private int proxyPort;
		public int ProxyPort { get { return int.Parse(PortNumericUpDown.Value.ToString()); } }

		private string username = string.Empty;
		public string Username { get { return UsernameTextBox.Text.Trim(); } }

		private string password = string.Empty;
		public string Password { get { return PasswordTextBox.Text.Trim(); } }

		public MainForm(string[] args)
		{
			InitializeComponent();

			foreach (string arg in args)
			{
				if (arg.ToLower() == "minimize")
				{
					this.WindowState = FormWindowState.Minimized;
				}
			}

			Instance = this;

			// Load settings
			Bing4FreeSettings.Load();

			// Load wallpaper thumbnail
			WallpaperThumbnailListView.Enabled = false;
			WallpaperThumbnailListView.MouseClick += new MouseEventHandler(WallpaperThumbnailListView_MouseClick);
			new Thread(LoadThumbnail).Start();

			#region " Load settings into components when form loaded "

			// Contruct wallpaper folder
			SaveFolderLinkLabel.Text = Bing4FreeSettings.settings.PicturesFolder;
			SaveFolderLinkLabel.LinkClicked += new LinkLabelLinkClickedEventHandler(SaveFolderLinkLabel_LinkClicked);
			SaveFolderButton.Click += new EventHandler(SaveFolderButton_Click);

			// Construct update interbal & switch interval combobox items
			List<ListItem> listItems = new List<ListItem>();
			listItems.Add(new ListItem("Disabled", "0"));
			listItems.Add(new ListItem("1 minute", "60000"));
			listItems.Add(new ListItem("5 minutes", "300000"));
			listItems.Add(new ListItem("10 minutes", "600000"));
			listItems.Add(new ListItem("30 minutes", "1800000"));
			listItems.Add(new ListItem("1 hour", "3600000"));
			listItems.Add(new ListItem("6 hours", "21600000"));
			listItems.Add(new ListItem("12 hours", "43200000"));

			UpdateIntervalComboBox.DataSource = listItems;
			UpdateIntervalComboBox.DisplayMember = "Text";
			UpdateIntervalComboBox.ValueMember = "Value";
			UpdateIntervalComboBox.SelectedIndex = GetSelectedTimerIndex(Bing4FreeSettings.settings.UpdateInterval);
			UpdateIntervalComboBox.SelectedIndexChanged += new EventHandler(UpdateIntervalComboBox_SelectedIndexChanged);

			listItems = new List<ListItem>();
			listItems.Add(new ListItem("Disabled", "0"));
			listItems.Add(new ListItem("1 minute", "60000"));
			listItems.Add(new ListItem("5 minutes", "300000"));
			listItems.Add(new ListItem("10 minutes", "600000"));
			listItems.Add(new ListItem("30 minutes", "1800000"));
			listItems.Add(new ListItem("1 hour", "3600000"));
			listItems.Add(new ListItem("6 hours", "21600000"));
			listItems.Add(new ListItem("12 hours", "43200000"));

			SwitchIntervalComboBox.DataSource = listItems;
			SwitchIntervalComboBox.DisplayMember = "Text";
			SwitchIntervalComboBox.ValueMember = "Value";
			SwitchIntervalComboBox.SelectedIndex = GetSelectedTimerIndex(Bing4FreeSettings.settings.SwitchInterval);
			SwitchIntervalComboBox.SelectedIndexChanged += new EventHandler(SwitchIntervalComboBox_SelectedIndexChanged);

			// Construct max latest wallpaper listing combobox items
			listItems = new List<ListItem>();
			listItems.Add(new ListItem("10 pictures", "10"));
			listItems.Add(new ListItem("25 pictures", "25"));
			listItems.Add(new ListItem("50 pictures", "50"));

			LatestImageComboBox.DataSource = listItems;
			LatestImageComboBox.DisplayMember = "Text";
			LatestImageComboBox.ValueMember = "Value";
			LatestImageComboBox.SelectedIndex = GetSelectedMaxIemIndex(Bing4FreeSettings.settings.MaxItem);
			LatestImageComboBox.SelectedIndexChanged += new EventHandler(LatestImageComboBox_SelectedIndexChanged);

			// Update now
			UpdateNowLinkLabel.LinkClicked += new LinkLabelLinkClickedEventHandler(UpdateNowLinkLabel_LinkClicked);

			// Construct desktop background style combobox items
			listItems = new List<ListItem>();
			listItems.Add(new ListItem("Stretched", "0"));
			listItems.Add(new ListItem("Centered", "1"));
			listItems.Add(new ListItem("Tiled", "2"));

			DesktopBackgroundStyleComboBox.DataSource = listItems;
			DesktopBackgroundStyleComboBox.DisplayMember = "Text";
			DesktopBackgroundStyleComboBox.ValueMember = "Value";
			DesktopBackgroundStyleComboBox.SelectedIndex = GetSelectedStyleIndex(Bing4FreeSettings.settings.WallpaperStyle);
			DesktopBackgroundStyleComboBox.SelectedIndexChanged += new EventHandler(DesktopBackgroundStyleComboBox_SelectedIndexChanged);

			// Construct automatic startup checkbox
			AutoStartupCheckBox.Checked = WindowsAPI.IsAutoStartup();
			AutoStartupCheckBox.CheckedChanged += new EventHandler(AutoStartupCheckBox_CheckedChanged);

			// Construct wallpaper thumbnail right-click option
			WallpaperThumbnailContextMenu.Click += new EventHandler(WallpaperThumbnailContextMenu_Click);

			// Construct update interval
			UpdateTimer.Tick += new EventHandler(UpdateTimer_Tick);
			if (Bing4FreeSettings.settings.UpdateInterval != "0")
			{
				if (!UpdateTimer.Enabled) UpdateTimer.Enabled = true;
				UpdateTimer.Interval = int.Parse(Bing4FreeSettings.settings.UpdateInterval);
			}
			else
			{
				UpdateTimer.Enabled = false;
			}

			// Construct switch interval
			SwitchTimer.Tick += new EventHandler(SwitchTimer_Tick);
			if (Bing4FreeSettings.settings.SwitchInterval != "0")
			{
				if (!SwitchTimer.Enabled) SwitchTimer.Enabled = true;
				SwitchTimer.Interval = int.Parse(Bing4FreeSettings.settings.SwitchInterval);
			}
			else
			{
				SwitchTimer.Enabled = false;
			}

			// Construct proxy
			UseProxyCheckBox.Checked = Bing4FreeSettings.settings.ProxyEnabled;
			ProxyServerTextBox.Text = Bing4FreeSettings.settings.ProxyServer;
			PortNumericUpDown.Value = Bing4FreeSettings.settings.Port;
			UsernameTextBox.Text = Bing4FreeSettings.settings.Username;
			PasswordTextBox.Text = Bing4FreeSettings.settings.Password;

			if (Bing4FreeSettings.settings.ProxyEnabled)
			{
				ProxyServerPanel.Enabled = true;
			}
			else
			{
				ProxyServerPanel.Enabled = false;
			}

			UseProxyCheckBox.CheckedChanged += new EventHandler(UseProxyCheckBox_CheckedChanged);
			SaveProxyLinkLabel.LinkClicked += new LinkLabelLinkClickedEventHandler(SaveProxyLinkLabel_LinkClicked);

			#endregion
		}

		private void MainForm_Load(object sender, EventArgs e)
		{
		}

		private void MainForm_Resize(object sender, EventArgs e)
		{
			if (this.WindowState == FormWindowState.Minimized)
			{
				this.Hide();
			}
		}

		private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
		{
			if (isBeginDownload)
			{
				e.Cancel = true;
			}
			else
			{
				DialogResult result = MessageBox.Show("Do you really want to exit?", "Question - Bing4Free", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
				if (result == DialogResult.No)
				{
					e.Cancel = true;
				}

				NotifyIcon.Dispose();
			}
		}

		public void LoadThumbnail()
		{
			DirectoryInfo di = new DirectoryInfo(Bing4FreeSettings.settings.PicturesFolder);
			if (!di.Exists)
			{
				di.Create();
			}
			string[] wallpaperCollection = Directory.GetFiles(Bing4FreeSettings.settings.PicturesFolder, "*.jpg");

			if (wallpaperCollection.Length > 0)
			{
				ArrayList capitalLetter = new ArrayList();
				capitalLetter.AddRange("A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z".Split(','));

				int maxItem = int.Parse(Bing4FreeSettings.settings.MaxItem);
				maxItem = maxItem < wallpaperCollection.Length ? maxItem : wallpaperCollection.Length;

				StatusLabel.Text = "Loading " + maxItem.ToString() + " of " + wallpaperCollection.Length.ToString() + " wallpaper(s) ...";
				WallpaperImageListCollection = new List<WallpaperImageList>();
				WallpaperThumbnailImageList = new ImageList();
				WallpaperThumbnailImageList.ImageSize = new Size(80, 43);
				WallpaperThumbnailImageList.ColorDepth = ColorDepth.Depth16Bit;

				Array.Sort(wallpaperCollection, new FileComparer(FileComparer.CompareBy.LastWriteTime));
				Array.Reverse(wallpaperCollection);

				for (int i = 0; i < maxItem; i++)
				{
					di = new DirectoryInfo(wallpaperCollection[i]);
					FileInfo fi = new FileInfo(di.FullName);
					string tooltip = string.Empty;

					if (fi.Exists)
					{
						using (FileStream fs = new FileStream(di.FullName, FileMode.Open, FileAccess.Read))
						{
							try
							{
								WallpaperThumbnailImageList.Images.Add(Image.FromStream(fs));
							}
							catch (Exception ex)
							{
								string error = ex.Message;
							}
						}

						string thumbnailName = string.Empty;
						string tmp = di.Name.Split('.')[0];
						for (int j = 0; j < tmp.Length; j++)
						{
							thumbnailName += (capitalLetter.Contains(tmp[j].ToString())) ? (j > 0) ? " " + tmp[j].ToString() : tmp[j].ToString() : tmp[j].ToString();
						}
						string thumbnailTooltip = fi.Name + Environment.NewLine + fi.LastWriteTime.ToString("yyyy-MM-dd") + Environment.NewLine + (fi.Length / 1024).ToString() + " KB";

						WallpaperImageListCollection.Add(new WallpaperImageList { Name = thumbnailName, Path = di.FullName, Tooltip = thumbnailTooltip });
					}
				}

				WallpaperThumbnailListView.BeginInvoke(new bindThumbnailDelegate(bindThumbnail));
			}
			else
			{
				WallpaperThumbnailListView.Enabled = true;
				Thread.Sleep(2000);
				if (!isBeginDownload)
				{
					this.BeginInvoke(new dialogUpdateNowDelegate(dialogUpdateNow));
				}
			}
		}

		private delegate void dialogUpdateNowDelegate();
		private void dialogUpdateNow()
		{
			if ((bool)(MessageBox.Show("You do not have any wallpaper. Do you want to download now?", "Question - Bing4Free", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes))
			{
				downloadWallpaper();
			}
		}

		private delegate void bindThumbnailDelegate();
		private void bindThumbnail()
		{
			WallpaperThumbnailListView.LargeImageList = WallpaperThumbnailImageList;
			for (int i = 0; i < WallpaperThumbnailImageList.Images.Count; i++)
			{
				WallpaperThumbnailListView.Items.Add(WallpaperImageListCollection[i].Name, i);
				WallpaperThumbnailListView.Items[i].ToolTipText = WallpaperImageListCollection[i].Tooltip;
			}
			WallpaperThumbnailListView.Enabled = true;
			StatusLabel.Text = "";
		}

		private void WallpaperThumbnailListView_MouseClick(object sender, MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Right && WallpaperThumbnailListView.SelectedItems.Count == 1)
			{
				WallpaperThumbnailContextMenu.Show(MousePosition);
			}
		}

		private void WallpaperThumbnailContextMenu_Click(object sender, EventArgs e)
		{
			string selectedWallpaper = WallpaperImageListCollection[WallpaperThumbnailListView.SelectedItems[0].ImageIndex].Path;
			WindowsAPI.SetDesktopBackground(new Bitmap(selectedWallpaper), GetWallpaperStyle(DesktopBackgroundStyleComboBox.SelectedItem.ToString()));
			Bing4FreeSettings.settings.LastImageShown = selectedWallpaper;
			Bing4FreeSettings.settings.Save();
		}

		private void SaveFolderLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			DirectoryInfo di = new DirectoryInfo(SaveFolderLinkLabel.Text);
			if (di.Exists)
			{
				Process.Start(SaveFolderLinkLabel.Text);
			}
			else
			{
				DialogResult result = MessageBox.Show("Path not found. Do you want to create now?", "Error - Bing4Free", MessageBoxButtons.YesNo, MessageBoxIcon.Error);
				if (result == DialogResult.Yes)
				{
					di.Create();
				}
			}
		}

		private void SaveFolderButton_Click(object sender, EventArgs e)
		{
			FolderBrowserDialog folderbrowserDialog = new FolderBrowserDialog();
			folderbrowserDialog.SelectedPath = Bing4FreeSettings.settings.PicturesFolder;
			DialogResult result = folderbrowserDialog.ShowDialog();
			if (result == DialogResult.OK)
			{
				Bing4FreeSettings.settings.PicturesFolder = folderbrowserDialog.SelectedPath;
				Bing4FreeSettings.settings.Save();
				SaveFolderLinkLabel.Text = folderbrowserDialog.SelectedPath;
				WallpaperThumbnailListView.Enabled = false;
				WallpaperThumbnailListView.Items.Clear();
				new Thread(LoadThumbnail).Start();
			}
		}

		private void UpdateIntervalComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			int interval = int.Parse(UpdateIntervalComboBox.SelectedValue.ToString());
			Bing4FreeSettings.settings.UpdateInterval = UpdateIntervalComboBox.SelectedValue.ToString();
			Bing4FreeSettings.settings.Save();

			if (interval != 0)
			{
				if (!UpdateTimer.Enabled) UpdateTimer.Enabled = true;
				UpdateTimer.Interval = interval;
			}
			else
			{
				UpdateTimer.Enabled = false;
			}

			settingsTab.Focus();
		}

		private void SwitchIntervalComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			int interval = int.Parse(SwitchIntervalComboBox.SelectedValue.ToString());
			Bing4FreeSettings.settings.SwitchInterval = interval.ToString();
			Bing4FreeSettings.settings.Save();

			if (interval != 0)
			{
				if (!SwitchTimer.Enabled) SwitchTimer.Enabled = true;
				SwitchTimer.Interval = interval;
			}
			else
			{
				SwitchTimer.Enabled = false;
			}

			settingsTab.Focus();
		}

		private void LatestImageComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			Bing4FreeSettings.settings.MaxItem = LatestImageComboBox.SelectedValue.ToString();
			Bing4FreeSettings.settings.Save();
			settingsTab.Focus();
			WallpaperThumbnailListView.Enabled = false;
			WallpaperThumbnailListView.Items.Clear();
			new Thread(LoadThumbnail).Start();
		}

		private void DesktopBackgroundStyleComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			Bing4FreeSettings.settings.WallpaperStyle = DesktopBackgroundStyleComboBox.SelectedValue.ToString();
			Bing4FreeSettings.settings.Save();
			settingsTab.Focus();
		}

		private void AutoStartupCheckBox_CheckedChanged(object sender, EventArgs e)
		{
			if (AutoStartupCheckBox.Checked)
			{
				WindowsAPI.AddStartupItem("Bing4Free", System.Reflection.Assembly.GetEntryAssembly().Location + " minimize");
			}
			else
			{
				WindowsAPI.RemoveStartupItem("Bing4Free");
			}
		}

		private int GetSelectedTimerIndex(string selectedValue)
		{
			int selectedIndex = 3;
			switch (selectedValue)
			{
				case "0": selectedIndex = 0; break;
				case "60000": selectedIndex = 1; break;
				case "300000": selectedIndex = 2; break;
				case "600000": selectedIndex = 3; break;
				case "1800000": selectedIndex = 4; break;
				case "3600000": selectedIndex = 5; break;
				case "21600000": selectedIndex = 6; break;
				case "43200000": selectedIndex = 7; break;
			}
			return selectedIndex;
		}

		private int GetSelectedMaxIemIndex(string selectedValue)
		{
			int selectedIndex = 1;
			switch (selectedValue)
			{
				case "10": selectedIndex = 0; break;
				case "25": selectedIndex = 1; break;
				case "50": selectedIndex = 2; break;
			}
			return selectedIndex;
		}

		private int GetSelectedStyleIndex(string selectedValue)
		{
			int selectedIndex = 0;
			switch (selectedValue)
			{
				case "Stretched": selectedIndex = 0; break;
				case "Centered": selectedIndex = 1; break;
				case "Tiled": selectedIndex = 2; break;
			}
			return selectedIndex;
		}

		public DesktopBackgroundStyle GetWallpaperStyle(string wallpaperStyle)
		{
			DesktopBackgroundStyle style = DesktopBackgroundStyle.Stretched;
			switch (wallpaperStyle)
			{
				case "Stretched":
					style = DesktopBackgroundStyle.Stretched;
					break;
				case "Centered":
					style = DesktopBackgroundStyle.Centered;
					break;
				case "Tiled":
					style = DesktopBackgroundStyle.Tiled;
					break;
			}
			return style;
		}

		private void downloadWallpaper()
		{
			isBeginDownload = true;
			WallpaperThumbnailListView.Enabled = false;
			settingsTab.Enabled = false;
			StatusLabel.Text = "Searching for new wallpaper ...";
			downloadThread = new Thread(Bing4FreeDownloader.DownloadWallpaper);
			downloadThread.Start();
		}

		private void UpdateNowLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			downloadWallpaper();
		}

		private void UpdateTimer_Tick(object sender, EventArgs e)
		{
			if (!IsBeginDownload)
			{
				UpdateTimer.Enabled = false;

				try
				{
					downloadWallpaper();
				}
				catch (Exception ex)
				{
					string error = ex.Message;
				}
			}

			UpdateTimer.Enabled = true;
		}

		private void SwitchTimer_Tick(object sender, EventArgs e)
		{
			string selectedWallpaper = string.Empty;

			if (WallpaperImageListCollection.Count > 0)
			{
				if (Bing4FreeSettings.settings.LastImageShown == null || Bing4FreeSettings.settings.LastImageShown.Length == 0)
				{
					selectedWallpaper = WallpaperImageListCollection[0].Path;
				}
				else
				{
					bool isFound = false;
					int i;

					for (i = 0; i < WallpaperImageListCollection.Count - 1; i++)
					{
						if (Bing4FreeSettings.settings.LastImageShown == WallpaperImageListCollection[i].Path)
						{
							isFound = true;
							break;
						}
					}

					if (isFound)
					{
						i += 1;
					}
					else
					{
						i = 0;
					}

					selectedWallpaper = WallpaperImageListCollection[i].Path;
				}

				WindowsAPI.SetDesktopBackground(new Bitmap(selectedWallpaper), GetWallpaperStyle(DesktopBackgroundStyleComboBox.SelectedItem.ToString()));
				Bing4FreeSettings.settings.LastImageShown = selectedWallpaper;
				Bing4FreeSettings.settings.Save();
			}
		}

		private void SaveProxyLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			Bing4FreeSettings.settings.ProxyEnabled = UseProxyCheckBox.Checked;
			Bing4FreeSettings.settings.ProxyServer = ProxyServerTextBox.Text.Trim();
			Bing4FreeSettings.settings.Port = int.Parse(PortNumericUpDown.Value.ToString());
			Bing4FreeSettings.settings.Username = UsernameTextBox.Text.Trim();
			Bing4FreeSettings.settings.Password = PasswordTextBox.Text.Trim(); // Password in clear text
			Bing4FreeSettings.settings.Save();
		}

		private void UseProxyCheckBox_CheckedChanged(object sender, EventArgs e)
		{
			if (UseProxyCheckBox.Checked)
			{
				ProxyServerPanel.Enabled = true;
			}
			else
			{
				ProxyServerPanel.Enabled = false;
			}
		}

		private void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
		{
			if (this.WindowState == FormWindowState.Minimized)
			{
				this.Show();
				this.WindowState = FormWindowState.Normal;
			}
			else if (this.WindowState == FormWindowState.Normal)
			{
				IntPtr iHandle = WindowsAPI.FindWindow(null, "Bing4Free");
				WindowsAPI.SetForegroundWindow(iHandle);
			}
		}

		private class ListItem
		{
			private string _Text;
			private string _Value;

			public ListItem(string text, string value)
			{
				_Text = text;
				_Value = value;
			}

			public string Text
			{
				get { return _Text; }
			}

			public string Value
			{
				get { return _Value; }
			}

			public override string ToString()
			{
				return Text;
			}
		}

		private class WallpaperImageList
		{
			public string Name { get; set; }
			public string Path { get; set; }
			public string Tooltip { get; set; }
		}

		private class FileComparer : IComparer
		{
			public enum CompareBy
			{
				Name,
				LastWriteTime,
				CreationTime,
				LastAccessTime,
				FileSize
			}

			int _CompareBy = (int)CompareBy.Name;

			public FileComparer() { }

			public FileComparer(CompareBy compareBy)
			{
				_CompareBy = (int)compareBy;
			}

			int IComparer.Compare(object x, object y)
			{
				int output = 0;
				FileInfo file1 = new FileInfo(x.ToString());
				FileInfo file2 = new FileInfo(y.ToString());
				switch (_CompareBy)
				{
					case (int)CompareBy.LastWriteTime:
						output = DateTime.Compare(file1.LastWriteTime, file2.LastWriteTime);
						break;
					case (int)CompareBy.CreationTime:
						output = DateTime.Compare(file1.CreationTime, file2.CreationTime);
						break;
					case (int)CompareBy.LastAccessTime:
						output = DateTime.Compare(file1.LastAccessTime, file2.LastAccessTime);
						break;
					case (int)CompareBy.FileSize:
						output = Convert.ToInt32(file1.Length - file2.Length);
						break;
					case (int)CompareBy.Name:
					default:
						output = (new CaseInsensitiveComparer()).Compare(file1.Name, file2.Name);
						break;
				}
				return output;
			}
		}
	}
}
